#ifndef _RENDERCALLBACK_H
#define _RENDERCALLBACK_H
#include <swbuf.h>
#include <swmodule.h>
#include <swkey.h>
#include <swbasicfilter.h>
#include <utilxml.h>
#include <osishtmlhref.h>
#include <thmlhtmlhref.h>

#define FAILED 0
#define SUCCEEDED 1
#define INHERITED 2

using namespace sword;

class ReturnSuccess 
{
public:
    ReturnSuccess(): data(""), success(FAILED) {}
    ReturnSuccess(char* data, int success): data(data), success(success) {}
    virtual ~ReturnSuccess() {}
    char* data;
    int success;
};


class RenderCallback {
public:
    virtual ~RenderCallback() {;}

    virtual ReturnSuccess run(sword::SWBuf& x, const char * token, 
			sword::BasicFilterUserData* userData) 
	{
        ReturnSuccess nullm("", INHERITED);
        return nullm;
    }
};

// Forward declarations
class OSISData;
class ThMLData;


class PyOSISHTMLHREF: public sword::OSISHTMLHREF 
{
private:
    RenderCallback* _callback;

public:
	// Create a class which can be inherited externally
#ifndef SWIG
	using sword::OSISHTMLHREF::MyUserData;
    class MyOsisUserData : public MyUserData {};
#endif
    
	PyOSISHTMLHREF(RenderCallback* callback)
    {
        _callback=callback;
    }

	static OSISData* getData(sword::BasicFilterUserData* f)
	{
        return (OSISData*) f;
	}
			
    virtual ~PyOSISHTMLHREF() 
	{ 
		delCallback();
	} 
	
	void delCallback() 
	{
		delete _callback;
		_callback = 0;
	}
	
	void setCallback(RenderCallback *cb)
	{
		delCallback();
		_callback = cb;
	}

     ReturnSuccess call(sword::SWBuf &buf, const char *token, sword::BasicFilterUserData *userData)          
	 { 
		 if (_callback) return _callback->run(buf, token, userData); 
         else 
		 {
			 ReturnSuccess nullm("", INHERITED);
             return nullm;
         }
     }

 protected:
	 virtual bool handleToken(sword::SWBuf &buf, const char *token, sword::BasicFilterUserData *userData)
	 {
		 ReturnSuccess result = call(buf, token, userData);
		 switch(result.success)
		 {
		 case INHERITED:
			 return sword::OSISHTMLHREF::handleToken(buf, token, userData);
		 case FAILED: 		 
			 return false;
		 case SUCCEEDED:
			 buf += result.data;
			 return true;
		 }        

		 return true;
     }
 };


class PyThMLHTMLHREF : public ThMLHTMLHREF {
private:
    RenderCallback* _callback;
public:
	// Create a class which can be inherited externally
#ifndef SWIG
	using sword::ThMLHTMLHREF::MyUserData;
	class MyThmlUserData : public MyUserData {};
#endif

	PyThMLHTMLHREF(RenderCallback* callback)
	{
		_callback=callback;
	}

	static ThMLData* getData(sword::BasicFilterUserData* f)
	{
        return (ThMLData*) f;
	}
	
    virtual ~PyThMLHTMLHREF() 
	{ 
		delCallback();
	} 
	
	void delCallback() 
	{
		delete _callback;
		_callback = 0;
	}
	
	void setCallback(RenderCallback *cb)
	{
		delCallback();
		_callback = cb;
	}

     ReturnSuccess call(sword::SWBuf &buf, const char *token, sword::BasicFilterUserData *userData)          
	 { 
		 if (_callback) return _callback->run(buf, token, userData); 
         else 
		 {
			 ReturnSuccess nullm("", INHERITED);
             return nullm;
         }
     }
protected:
	 virtual bool handleToken(sword::SWBuf &buf, const char *token, sword::BasicFilterUserData *userData)
	 {
		 ReturnSuccess result = call(buf, token, userData);
		 switch(result.success)
		 {
		 case INHERITED:
			 return sword::ThMLHTMLHREF::handleToken(buf, token, userData);
		 case FAILED: 		 
			 return false;
		 case SUCCEEDED:
			 buf += result.data;
			 return true;
		 }        

		 return true;
     }

public:


};

class OSISData : 
#ifndef SWIG
public PyOSISHTMLHREF::MyOsisUserData {
#else
// trick SWIG into thinking this is not inherited from an inner class...
public sword::BasicFilterUserData 
{
public:
        bool osisQToTick;
        bool inBold;
        bool inXRefNote;
        bool BiblicalText;
        int suspendLevel;
        SWBuf wordsOfChristStart;
        SWBuf wordsOfChristEnd;
        SWBuf lastTransChange;
        SWBuf w;
        SWBuf fn;
        SWBuf version;

#endif //!SWIG
};

class ThMLData : 
#ifndef SWIG
public PyThMLHTMLHREF::MyThmlUserData {
#else
// trick SWIG into thinking this is not inherited from an inner class...
public sword::BasicFilterUserData 
{
public:
		SWBuf inscriptRef;
		bool SecHead;
		bool BiblicalText;
		SWBuf version;
		XMLTag startTag;	

#endif //!SWIG
};

#endif // _RENDERCALLBACK_H
